package Model;

import Controller.Main;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author HaTschE
 */
public class CreateCSV {



//    Export of the CSV file
    public boolean createCSV() {
        this.calculateAttributes();
//        this.normalize();
        this.assignClasses();
        FileWriter fstream = null;
        try {
            if (!Main.TEST) {
                fstream = new FileWriter("train.csv");
            } else {
                fstream = new FileWriter("test.csv");
            }
            BufferedWriter out = new BufferedWriter(fstream);

            Country currentCountry = Controller.Main.CONTROL.getCountries().get(0);
            out.write("Country Name");
            for (int j = 0; j < currentCountry.getIndicators().size(); j++) {
                out.write("," + currentCountry.getIndicators().get(j).getName() + "/Change");
                out.write("," + currentCountry.getIndicators().get(j).getName() + "/GDP");
                out.write("," + currentCountry.getIndicators().get(j).getName() + "/ChangeByGDP");
                for (int k = 0; k < currentCountry.getIndicators().get(j).getSubIndicators().size(); k++) {
                    out.write("," + currentCountry.getIndicators().get(j).getName() + "" + currentCountry.getIndicators().get(j).getSubIndicators().get(k).getName() + "/Change");
                    out.write("," + currentCountry.getIndicators().get(j).getName() + "" + currentCountry.getIndicators().get(j).getSubIndicators().get(k).getName() + "/GDP");
                    out.write("," + currentCountry.getIndicators().get(j).getName() + "" + currentCountry.getIndicators().get(j).getSubIndicators().get(k).getName() + "/ChangeByGDP");
                }
            }
//            out.write(",Inflation");
            out.write(",Crisis");
            int numberOfYears = currentCountry.getIndicators().get(0).getYears().size();

            for (int i = 0; i < Controller.Main.CONTROL.getCountries().size(); i++) {
                currentCountry = Controller.Main.CONTROL.getCountries().get(i);
                for (int l = 0; l < numberOfYears; l++) {
                    for (int m = 0; m < 4; m++) {
                        String toWrite = "";
//                        toWrite += "\n";
                        toWrite += "\n" + currentCountry.getName();
                        for (int j = 0; j < currentCountry.getIndicators().size(); j++) {
                            toWrite += "," + currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyAbsoluteChange()[m];
//                            toWrite += currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyAbsoluteChange()[m];
                            toWrite += "," + currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyByGDP()[m];
                            toWrite += "," + currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyChangeByGDP()[m];
                            for (int k = 0; k < currentCountry.getIndicators().get(j).getSubIndicators().size(); k++) {
                                toWrite += "," + currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyAbsoluteChange()[m];
                                toWrite += "," + currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyByGDP()[m];
                                toWrite += "," + currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyChangeByGDP()[m];
                            }
                        }
//                        Remove empty lines
                        if (!toWrite.contains("null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null")) {
//                            if (l < currentCountry.getInflation().size()) {
//                                toWrite += "," + currentCountry.getInflation().get(l);
//                            } else {
//                                toWrite += ",?";
//                            }
                            toWrite += "," + currentCountry.getIndicators().get(0).getYears().get(l).getQuarterlyCrisis()[m];
//                            Remove lines with only missing values
                            if (toWrite.length() > 200) {
                                if (Main.TEST == false && toWrite.contains("YES")) {
                                    for (int o = 0; o < 7; o++) {
                                        toWrite = toWrite.replace("null", "?");
                                        out.write(toWrite);
                                    }
                                }
                                toWrite = toWrite.replace("null", "?");
                                out.write(toWrite);
                            }
                        }
                    }

                }
            }
            //Close the output stream
            out.close();
            return true;
        } catch (IOException ex) {
            Logger.getLogger(CreateCSV.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        } finally {
            try {
                fstream.close();
            } catch (IOException ex) {
                Logger.getLogger(CreateCSV.class.getName()).log(Level.SEVERE, null, ex);
                return false;
            }
        }
    }

    private boolean assignClasses() {
        for (int i = 0; i < Controller.Main.CONTROL.getInterestrates().size(); i++) {
            int countryIndex = Controller.Main.CONTROL.getInterestrates().get(i).getCountryIndex();
            Country currentCountry = Controller.Main.CONTROL.getCountries().get(countryIndex);

            String quarter = Controller.Main.CONTROL.getInterestrates().get(i).getQuarter();

            for (int j = 0; j < currentCountry.getIndicators().get(0).getYears().size() - 1; j++) {
                if (currentCountry.getIndicators().get(0).getYears().get(j).getName().contains(quarter.substring(0, quarter.length() - 2))) {
                    int quart = Integer.parseInt(quarter.substring(quarter.length() - 1, quarter.length()));
                    if (quart < 3) {
                        currentCountry.getIndicators().get(0).getYears().get(j).getQuarterlyCrisis()[(quart + 1)] = "YES";
                    } else {
                        currentCountry.getIndicators().get(0).getYears().get(j + 1).getQuarterlyCrisis()[(quart + 1) % 4] = "YES";
                    }
                    if (Controller.Main.CONTROL.getInterestrates().get(i).getValue() < 1.5) {
                        return true;
                    }
                }
            }
        }
        return true;
    }

//    Crisis data based on percente of the entire data set
    private boolean assignClasses2() {
        int numberOfQuarters = 0;
        for (int i = 0; i < Controller.Main.CONTROL.getCountries().size(); i++) {
            Country currentCountry = Controller.Main.CONTROL.getCountries().get(i);
            for (int j = 0; j < currentCountry.getIndicators().get(0).getYears().size(); j++) {
                if (!currentCountry.getIndicators().get(0).getYears().get(j).getQuarterlyOrg()[0].contains("?")) {
                    numberOfQuarters += 4;
                }
            }
        }
        int crisisRange = (int) (numberOfQuarters * ((double) Controller.Main.CONTROL.getPercentages()[1] / 100));
        for (int i = 0; i < Controller.Main.CONTROL.getInterestrates().size(); i++) {
            int countryIndex = Controller.Main.CONTROL.getInterestrates().get(i).getCountryIndex();
            Country currentCountry = Controller.Main.CONTROL.getCountries().get(countryIndex);

            String quarter = Controller.Main.CONTROL.getInterestrates().get(i).getQuarter();

            for (int j = 0; j < currentCountry.getIndicators().get(0).getYears().size() - 1; j++) {

                if (currentCountry.getIndicators().get(0).getYears().get(j).getName().contains(quarter.substring(0, quarter.length() - 2))) {
                    int quart = Integer.parseInt(quarter.substring(quarter.length() - 1, quarter.length()));
                    if (quart < 3) {
                        currentCountry.getIndicators().get(0).getYears().get(j).getQuarterlyCrisis()[(quart + 1)] = "YES";
                        crisisRange--;
                    } else {
                        currentCountry.getIndicators().get(0).getYears().get(j + 1).getQuarterlyCrisis()[(quart + 1) % 4] = "YES";
                        crisisRange--;
                    }
                    if (crisisRange == 0) {
                        return true;
                    }
                }
            }
        }
        return true;
    }

    private void calculateAttributes() {
        for (int i = 0; i < Controller.Main.CONTROL.getCountries().size(); i++) {
            Country currentCountry = Controller.Main.CONTROL.getCountries().get(i);
            int numberOfYears = currentCountry.getIndicators().get(0).getYears().size();
            for (int l = 0; l < numberOfYears; l++) {
                for (int m = 0; m < 4; m++) {
                    for (int j = 0; j < currentCountry.getIndicators().size(); j++) {
                        double[] values = {-987.0, -987.0, -987.0};
                        String old, current, oldGDP, currentGDP;
                        if (m != 0) {
                            if (!currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyOrg()[m - 1].contains("?")
                                    && !currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyOrg()[m].contains("?")) {
                                old = currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyOrg()[m - 1];
                                current = currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyOrg()[m];

                                oldGDP = currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyGDP()[m - 1];
                                currentGDP = currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyGDP()[m];
                                values = this.calculate(old, current, oldGDP, currentGDP);
                            }
                        } else {
                            if (l != 0 && !(currentCountry.getIndicators().get(j).getYears().get(l - 1).getQuarterlyOrg()[3] + "").contains("null")) {
                                if (!currentCountry.getIndicators().get(j).getYears().get(l - 1).getQuarterlyOrg()[3].contains("?")
                                        && !currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyOrg()[m].contains("?")) {
                                    old = currentCountry.getIndicators().get(j).getYears().get(l - 1).getQuarterlyOrg()[3];
                                    current = currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyOrg()[m];

                                    oldGDP = currentCountry.getIndicators().get(j).getYears().get(l - 1).getQuarterlyGDP()[3];
                                    currentGDP = currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyGDP()[m];
                                    values = this.calculate(old, current, oldGDP, currentGDP);
                                }
                            }
                        }
                        String help = "";
                        if (values[0] != -987.0 && !Double.isNaN(values[0]) && !Double.isInfinite(values[0])) {
                            help = "" + (BigDecimal.valueOf(values[0]).toEngineeringString());
                            currentCountry.getIndicators().get(j).getYears().get(l).setQuarterlyAbsoluteChange(m, help);
                        }
                        if (values[1] != -987.0 && !Double.isNaN(values[1]) && !Double.isInfinite(values[1])) {
                            help = "" + (BigDecimal.valueOf(values[1]).toEngineeringString());
                            currentCountry.getIndicators().get(j).getYears().get(l).setQuarterlyByGDP(m, help);
                        }
                        if (values[2] != -987.0 && !Double.isNaN(values[2]) && !Double.isInfinite(values[2])) {
                            help = "" + (BigDecimal.valueOf(values[2]).toEngineeringString());
                            currentCountry.getIndicators().get(j).getYears().get(l).setQuarterlyChangeByGDP(m, help);
                        }
                        for (int k = 0; k < currentCountry.getIndicators().get(j).getSubIndicators().size(); k++) {
                            if (m != 0) {
                                if (!currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyOrg()[m - 1].contains("?")
                                        && !currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyOrg()[m].contains("?")) {

                                    old = currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyOrg()[m - 1];
                                    current = currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyOrg()[m];

                                    oldGDP = currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyGDP()[m - 1];
                                    currentGDP = currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyGDP()[m];
                                    values = this.calculate(old, current, oldGDP, currentGDP);
                                }
                            } else {
                                if (l != 0 && !(currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l - 1).getQuarterlyOrg()[3] + "").contains("null")) {
                                    if (!currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l - 1).getQuarterlyOrg()[3].contains("?")
                                            && !currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyOrg()[m].contains("?")) {
                                        old = currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l - 1).getQuarterlyOrg()[3];
                                        current = currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyOrg()[m];

                                        oldGDP = currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l - 1).getQuarterlyGDP()[3];
                                        currentGDP = currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyGDP()[m];
                                        values = this.calculate(old, current, oldGDP, currentGDP);
                                    }
                                }
                            }

                            if (values[0] != -987.0 && !Double.isNaN(values[0]) && !Double.isInfinite(values[0])) {
                                help = "" + (BigDecimal.valueOf(values[0]).toEngineeringString());
                                currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).setQuarterlyAbsoluteChange(m, help);
                            }
                            if (values[1] != -987.0 && !Double.isNaN(values[1]) && !Double.isInfinite(values[1])) {
                                help = "" + (BigDecimal.valueOf(values[1]).toEngineeringString());
                                currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).setQuarterlyByGDP(m, help);
                            }
                            if (values[2] != -987.0 && !Double.isNaN(values[2]) && !Double.isInfinite(values[2])) {
                                help = "" + (BigDecimal.valueOf(values[2]).toEngineeringString());
                                currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).setQuarterlyChangeByGDP(m, help);
                            }
                        }
                    }

                }
            }
        }
    }

    public double[] calculate(String olds, String currents, String oldGDPs, String currentGDPs) {
        double[] values = new double[3];
        double old = 0.0, current = 0.0, oldGDP = 0.0, currentGDP = 0.0;
        if (null != olds) {
            old = Double.parseDouble(olds);
        }
        if (null != currents) {
            current = Double.parseDouble(currents);
        }
        if (null != oldGDPs) {
            oldGDP = Double.parseDouble(oldGDPs);
        }
        if (null != currentGDPs) {
            currentGDP = Double.parseDouble(currentGDPs);
        }
//        quarterly change in absolute value of external debt of XXX
        if (null != currents && null != olds) {
            values[0] = (current - old) / old;
        } else {
            values[0] = -987.0;
        }
        if (values[0] > 3 || values[0] < -3) {
            values[0] = -987.0;
        }

//        ratios of external debt of XXX
        if (null != currents && null != currentGDPs) {
            values[1] = current / currentGDP;
        } else {
            values[1] = -987.0;
        }
//        No change data therefore no outliers
//        if (values[1] > 3 || values[1] < -3) {
//            values[1] = -987.0;
//        }
        //                quarterly change in ratios of external debt of XXX to GDP
        if (null != currents && null != olds && null != currentGDPs && null != oldGDPs) {
            values[2] = (current / currentGDP - old / oldGDP) / (old / oldGDP);
        } else {
            values[2] = -987.0;
        }
        if (values[2] > 3 || values[2] < -3) {
            values[2] = -987.0;
        }
        return values;
    }

    public CreateCSV() {
    }
//    Unused normalization of the dataset
//    public void normalize() {
//        Country currentCountry = Controller.Main.CONTROL.getCountries().get(0);
//        int numberOfYears = currentCountry.getIndicators().get(0).getYears().size();
//
//        for (int i = 0; i < Controller.Main.CONTROL.getCountries().size(); i++) {
//            currentCountry = Controller.Main.CONTROL.getCountries().get(i);
//            for (int j = 0; j < currentCountry.getIndicators().size(); j++) {
//                double max = 0;
//                String test = "999999999999999999";
//                double min = Double.parseDouble(test);
//                for (int l = 0; l < numberOfYears; l++) {
//                    for (int m = 0; m < 4; m++) {
//                        String help = currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyData()[m];
//                        if (!help.contains("?")) {
//                            double value = Double.parseDouble(help);
//                            if (value > max) {
//                                max = value;
//                            }
//                            if (value < min) {
//                                min = value;
//                            }
//                        }
//                    }
//                }
//                double diff = max - min;
//
//                for (int l = 0; l < numberOfYears; l++) {
//                    for (int m = 0; m < 4; m++) {
//                        String help = currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyData()[m];
//                        if (!help.contains("?")) {
//                            double value = Double.parseDouble(help);
//
//                            if (diff != 0) {
//                                double test3 = value - min;
//                                double test2 = test3 / diff;
//                                currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyData()[m] = "" + test2;
//                            } else {
//                                currentCountry.getIndicators().get(j).getYears().get(l).getQuarterlyData()[m] = "" + 0.5;
//                            }
//                        }
//                    }
//                }
//
//            }
//
//            for (int j = 0; j < currentCountry.getIndicators().size(); j++) {
//                for (int k = 0; k < currentCountry.getIndicators().get(j).getSubIndicators().size(); k++) {
//                    double max = 0;
//                    String test = "999999999999999999";
//                    double min = Double.parseDouble(test);
//                    for (int l = 0; l < numberOfYears; l++) {
//                        for (int m = 0; m < 4; m++) {
//                            String help = currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyData()[m];
//                            if (!help.contains("?")) {
//                                double value = Double.parseDouble(help);
//                                if (value > max) {
//                                    max = value;
//                                }
//                                if (value < min) {
//                                    min = value;
//                                }
//                            }
//                        }
//                    }
////                    System.out.println("max: " + max + " min: " + min);
//                    double diff = max - min;
//                    for (int l = 0; l < numberOfYears; l++) {
//                        for (int m = 0; m < 4; m++) {
//                            String help = currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyData()[m];
//                            if (!help.contains("?")) {
//                                double value = Double.parseDouble(help);
//                                if (diff != 0) {
//                                    double test3 = value - min;
//                                    double test2 = ((double) test3) / ((double) diff);
//                                    currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyData()[m] = "" + test2;
//                                } else {
//                                    currentCountry.getIndicators().get(j).getSubIndicators().get(k).getYears().get(l).getQuarterlyData()[m] = "" + 0.5;
//                                }
//
//                            }
//
//                        }
//                    }
//                }
//            }
//        }
//    }
//    Assign Crisis classes based on intrest rates
}
